<template>
  <el-dialog
    :title="deptDialogTitle"
    :visible.sync="visible"
    width="35%"
    top="13vh"
    :before-close="closeDeptDialogHandle"
    :close-on-click-modal="false">
    <el-form v-loading="dataLoad" :model="deptForm" :rules="deptRules" ref="deptForm"
             @keyup.enter.native="enterFromHandle" label-width="85px">
      <el-form-item label="部门名称" prop="deptName">
        <el-input v-model="deptForm.deptName" maxlength="20" placeholder="部门名称"></el-input>
      </el-form-item>
      <el-form-item label="父级部门" prop="parentDeptId">
        <tree-select :data-obj="deptForm" prop-key="parentDeptId" node-key="deptId" :tree-data="deptTreeData"
                     :default-props="defaultProps" @node-click="parentDeptChangeHandle" />
      </el-form-item>
      <el-form-item label="排序等级" prop="sort">
        <el-input v-model.number="deptForm.sort" maxlength="5" placeholder="排序等级"></el-input>
      </el-form-item>
    </el-form>
    <span slot="footer">
      <el-button @click="closeDeptDialogHandle(false)">取消</el-button>
      <el-button v-show="!optType" :disabled="loading" type="primary" @click="saveDeptHandle">添加</el-button>
      <el-button v-show="optType" :disabled="loading" type="primary" @click="updateDeptHandle">修改</el-button>
    </span>
  </el-dialog>
</template>

<script>
  import TreeSelect from '@/components/common/tree-select'

  export default {
    name: "dept-save-update",
    components: { TreeSelect },
    data () {
      return {
        // 弹出框显示状态[true-显示 false-隐藏]
        visible: false,
        // 系统部门表单对象
        deptForm: {
          // 部门主键
          deptId: undefined,
          // 父级部门主键
          parentDeptId: '0',
          // 父级部门路径
          deptPath: '',
          // 部门名称
          deptName: '',
          // 排序等级
          sort: '',
        },
        // 部门树数据列表
        deptTreeData: [],
        // 部门树节点字段配置
        defaultProps: {
          children: "children",
          label: "deptName",
          disabled: "disabled",
        },
        // 弹出框标题
        deptDialogTitle: undefined,
        // 部门操作类型[false-添加 true-修改]
        optType: false,
        // 数据是否加载[false-不加载 true-加载]
        dataLoad: false,
        // 按钮是否可被点击[false-可以被点击 true-不可被点击]
        buttonLoad: false,
        // 系统部门表单校验对象
        deptRules: {
          parentDeptId: [
            { required: true, message: '请选择父级部门', trigger: 'blur' }
          ],
          deptName: [
            { required: true, message: '部门名称不能为空', trigger: 'blur' }
          ],
          sort: [
            { required: true, message: '排序等级不能为空', trigger: 'blur' },
            { type: 'number', message: '排序等级必须为数字值'}
          ],
        }
      }
    },
    computed: {
      // 加载状态
      loading() {
        return this.dataLoad || this.buttonLoad;
      }
    },
    methods: {
      /**
       * 初始化系统部门操作弹出框方法
       * @param {Object}  dept    系统部门对象
       * @param {boolean} optType 系统部门操作类型[true-修改 false-添加]
       */
      initDeptDialog(dept, optType) {
        // 打开弹出框
        this.visible = true;
        this.optType = optType;
        this.deptDialogTitle = optType ? '修改部门' : '添加部门';
        // console.log('dept', dept, 'optType', optType)
        let deptId = '';
        if (optType) {
          // 修改
          deptId = dept.deptId;

          this.$nextTick(() => {
            let deptForm = this.deptForm;
            deptForm.deptId = dept.deptId;
            deptForm.parentDeptId = dept.parentDeptId;
            deptForm.deptPath = dept.deptPath;
            deptForm.deptName = dept.deptName;
            deptForm.sort = dept.sort;
          });
        } else {
          // 添加
          this.$nextTick(() => {
            if (!!dept) {
              let deptForm = this.deptForm;
              deptForm.parentDeptId = dept.deptId;
              deptForm.deptPath = dept.deptPath;
            }
          });
          this.getNextSort(dept);
        }
        this.getDeptTree(deptId);
      },
      /**
       * 获取部门数据树方法
       * @param {string} deptId 部门主键
       */
      getDeptTree(deptId) {
        // 开始部门树加载
        this.dataLoad = true;
        this.$axios.$get('/sys/dept/tree', { params: { deptId }})
          .then(({ data }) => {
            this.deptTreeData.push(data);
          })
          .catch(() => {})
          .finally(() => {
            // 部门树加载结束
            this.dataLoad = false;
          })
      },
      /**
       * 获取下一个排序等级
       * 根据部门对象，获取该部门的默认下一个排序等级
       * @param {Object} dept 部门对象
       */
      getNextSort(dept = {}) {
        this.$axios.$get('/sys/dept/next/sort', { params: { deptId: dept.deptId }})
          .then(({ data }) => {
            this.deptForm.sort = data
          })
          .catch(() => {})
      },
      // 表单回车事件
      enterFromHandle() {
        if (this.optType) {
          this.updateDeptHandle()
        } else {
          this.saveDeptHandle()
        }
      },
      /**
       * 保存部门数据事件
       */
      saveDeptHandle() {
        this.$refs.deptForm.validate((valid) => {
          if (!valid) {
            return false;
          }
          let deptForm = this.deptForm

          let numberRegex = /^\d+$/
          if (!numberRegex.test(deptForm.sort)) {
            this.notify('info', "温馨提示", '排序等级只能输入纯数字')
            return false;
          }
          // 按钮不可被点击
          this.buttonLoad = true;
          this.$axios.$post('/sys/dept/save', deptForm)
            .then(() => {
              this.notify('success', "添加成功", `成功添加'${deptForm.deptName}'部门`)

              // 关闭弹出框
              this.closeDeptDialogHandle(true)
            })
            .catch(() => {})
            .finally(() => {
              // 按钮恢复可点击
              this.buttonLoad = false
            })
        });
      },
      /**
       * 修改部门数据事件
       */
      updateDeptHandle() {
        this.$refs.deptForm.validate((valid) => {
          if (!valid) {
            return false;
          }
          let deptForm = this.deptForm

          let numberRegex = /^\d+$/
          if (!numberRegex.test(deptForm.sort)) {
            this.notify('info', "温馨提示", '排序等级只能输入纯数字')
            return false;
          }
          // 按钮不可被点击
          this.buttonLoad = true;
          this.$axios.$post('/sys/dept/update', deptForm)
            .then(() => {
              this.notify('success', "修改成功", `成功修改'${deptForm.deptName}'部门`)

              // 关闭弹出框
              this.closeDeptDialogHandle(true)
            })
            .catch(() => {})
            .finally(() => {
              // 按钮恢复可点击
              this.buttonLoad = false
            })
        });
      },
      /**
       * 弹出框关闭处理事件
       * @param {boolean|function} bool 是否刷新父级组件[true-刷新 false-不刷新]
       */
      closeDeptDialogHandle(bool) {
        // 关闭弹出框
        this.visible = false;
        // 清空系统部门表单对象信息
        this.$refs.deptForm.resetFields()
        // 手动清空部门主键
        this.deptForm.deptId = ''
        // 手动清空部门树数据
        this.deptTreeData = []

        // 此处判断触发事件是否是弹出框自带关闭事件
        if (typeof bool === 'function') {
          bool = false
        }
        // 向上传递事件
        this.$emit('close-dialog', bool)
      },
      /**
       * 部门树选择项发生改变事件
       * @param node        部门选择树选中节点
       * @param instanceId
       */
      parentDeptChangeHandle(node, instanceId) {
        let deptForm = this.deptForm
        deptForm.parentDeptId = node.deptId
        deptForm.deptPath = node.deptPath
        // 清除校验状态
        this.$refs.deptForm.clearValidate(['parentDeptId'])
      },
    }
  }
</script>
